package PolymorphismInstanceof;


/**
 *
 * 面向对象的特征之三：多态性
 *
 * 1、理解多态性：可以理解为一个事物的多种形态
 *
 * 2、何为多态性：
 *      对象的多态性：父类的引用指向子类的对象（或子类的对象赋给父类的引用）
 *
 * 3、多态性的使用：虚拟方法的调用
 *      有呢对象的多态性以后，我们在编译期，只能调用父类中声明的方法，但在运行期，我们实际执行的是子类重写父类的方法
 *      总结：编译看左边；运行看右边
 *
 * 4、多态性的使用前提：（1）类的继承关系 （2）方法的重写
 *
 * 5、对象的多态性，只适用于方法，不适用于属性
 *
 * 6、有了对象的多态性以后，内存中实际上是加载了子类特有的属性和方法的，但是由于变量声明为父类类型，导致了编译时只能调用
 *    父类中声明的属性和方法。子类特有的属性和方法不能再调用
 *
 *    如何才能调用子类特有的属性和方法？
 *    向下转型：使用强制类型转换符。
 *    Man m1 = (Man)p2;
 *    使用强行转换时可能出现ClassCastException异常
 *
 */

/**
 *
 * instanceof关键字的使用：
 *
 * a instanceof A:判断对象a 是否是类 A 的实例。如果是返回true，如果不是返回false。
 *
 *使用情境：为了避免在向下转型时出现ClassCastException的异常。我们在向下转型之前，先进行instanceof的判断，
 *        一旦返回true，就向下转型。如果返回false，不进行向下转型。
 */


public class PersonTest {
    public static void main(String[] args) {

        Person p1 = new Person();
        p1.eat();

        Man man = new Man();
        man.eat();
        man.age = 25;
        man.earnMoney();

        //************************************

        //子类对象的多态性：父类的引用指向子类的对象
        Person p2 = new Man();
        p2.eat();
        p2.walk();

        if (p2 instanceof Women){
            Women w1 = (Women) p2;
            System.out.println("*****Women****");
        }

        if (p2 instanceof Man){
            Man m1 = (Man)p2;
            System.out.println("****Man****");
        }



//        Person p3 = new Women();


    }
}
